#!/usr/bin/env python
import itertools
import cherrypy
import os
import threading
import random
import time
import fileinput
import  json
from AccuracyWeight import AccuracyWeight
from HybridWeight import HybridWeight

class OneMarkov(object):
    def __init__(self):
        self.dic1={}
        self.average=0
        self.count=0
        self.no_request=0
        self.no_of_request=0
        self.n=0

    def initial_train(self):
        dic2={}
        n=0
        for line in fileinput.input(['D:\\python\\DATSET\\3daysdata\\D\\train_d.csv']):
                try:
                        self.dic1=self.train(line,self.dic1)
                except:
                    continue
        return self.dic1
             
    def train(self,line,dic1): # this is a training method 
        count1=0
        print "INSIDE TRAIN"
        line2= line.strip().rstrip(',')
        line1=line2.split(',') # to get the elements/domain number in a sessions
        length=len(line1)-1
        for i in range(0,length):
            j=i+1
            if dic1.has_key(line1[i]):
                value=dic1.get(line1[i])
                count1=value[0]
                dic2=value[1]
                count1=int(count1)+1
                if dic2.has_key(line1[j]):
                    dic2[line1[j]]=int(dic2.get(line1[j]))+1
                else:
                    dic2[line1[j]]=1
                    dic1[line1[i]]=(count1,dic2)
            else:
                count2=1
                dic3={}
                dic3[line1[j]]=1
                dic1[line1[i]]=(count2,dic3)
        return dic1
    
        
    
    def recommend(self,d1,dic1):
        list1 =[]
        value=dic1.get(d1)
        if (value==None):
            return list1
        hash= value[1]
        list1=sorted(hash.iteritems(), key=lambda (k,v): (v,k))
        list1.reverse()
        len1=len(list1)
        resultlist=[]
        for u in range(0,len1):
            resultlist.append((list1[u])[0])
        return resultlist[0:5]
    
    
    def evaluate(self,recommendationlist,actual,count,average):
        correct=0
        if actual in recommendationlist:
            correct=1
            average = self.calculateAccuracy(1,average,count)
            return (average,count,correct)
        else:
            correct=0
            average=self.calculateAccuracy(0,average,count)
            return (average,count,correct)
        
    def calculateAccuracy(self,correct,average,count):

            return ((int(count)-1)*float(average)+int(correct))/int(count)
        
        
        
class HelloWorld(object):
    def __init__(self):
        self.thread1 = myThread()
        self.thread1.start()
        
    def datajson(self):
#        result = "{\"accuracy\":"+"\""+self.thread1.getAccuracy()+"\",\"coverage\":"+"\""+self.thread1.getCoverage()+"\",\"session\":"+"\""+self.thread1.getPartialSession()+"\",\"recommendation\":"+"\""+self.thread1.getRecommendationList()+"\",\"correct\":"+"\""+self.thread1.getCorrect()+"\",\"actual\":"+"\""+self.thread1.getActual()+"\"""}"
        result="{\"accuracy\":"+"\""+self.thread1.getAccuracy()+"\",\"coverage\":"+"\""+self.thread1.getCoverage()+"\",\"session\":"+"\""+self.thread1.getPartialSession()+"\",\"recommendation\":"+"\""+self.thread1.getRecommendationList()+"\",\"correct\":"+"\""+self.thread1.getCorrect()+"\",\"actual\":"+"\""+self.thread1.getActual()+"\",\"accuracy_aw\":"+"\""+self.thread1.getAccuracy_aw()+"\",\"coverage_aw\":"+"\""+self.thread1.getCoverage_aw()+"\",\"recommendation_aw\":"+"\""+self.thread1.getRecommendationList_aw()+"\",\"correct_aw\":"+"\""+self.thread1.getCorrect_aw()+"\",\"accuracy_hw\":"+"\""+self.thread1.getAccuracy_hw()+"\",\"coverage_hw\":"+"\""+self.thread1.getCoverage_hw()+"\",\"recommendation_hw\":"+"\""+self.thread1.getRecommendationList_hw()+"\",\"correct_hw\":"+"\""+self.thread1.getCorrect_hw()+"\"}"
        self.thread1.semaphore.release()
        return result
    
    
    #===========================================================================
    # def accuracyjson(self):
    #    return "{\"accuracy\":"+"\""+self.thread1.getAccuracy()+"\""+"}"
    # def coveragejson(self):
    #    return "{\"coverage\":"+"\""+self.thread1.getCoverage()+"\""+"}"
    # def partialsessionjson(self):
    #    return "{\"session\":"+"\""+self.thread1.getPartialSession()+"\""+"}"
    # def recommendationlistjson(self):
    #    return "{\"recommendation\":"+"\""+self.thread1.getRecommendationList()+"\""+"}"
    # def correctjson(self):
    #    return "{\"correct\":"+"\""+self.thread1.getCorrect()+"\""+"}"
    # def actualjson(self):
    #    return "{\"actual\":"+"\""+self.thread1.getActual()+"\""+"}"
    #===========================================================================
    
                     
    #===========================================================================
    # accuracyjson.exposed = True
    # coveragejson.exposed = True
    # partialsessionjson.exposed = True
    # recommendationlistjson.exposed = True
    # correctjson.exposed = True
    # actualjson.exposed = True
    #===========================================================================
    datajson.exposed = True

class myThread (threading.Thread):
    def __init__(self):
        self.accuracy = 0
        self.coverage=0
        self.no_of_request=0
        self.no_request=0
        self.dic1={}
        self.recomendation_list=[]
        self.recomendation_list_aw=[]
        self.recomendation_list_hw=[]
        self.count=0
        self.correct=-1
        self.actual=""
        self.patial_session=[]
        self.aw=AccuracyWeight()
        self.hw=HybridWeight()
        self.results_aw=[100,0,0]
        self.results_hw=[100,0,0]
        self.semaphore = threading.Semaphore(1)
        threading.Thread.__init__(self)
        
    def run(self):
        om= OneMarkov()
        self.aw.train()
        self.hw.train()
        self.dic1=om.initial_train()
        for line in fileinput.input(['D:\\python\\DATSET\\3daysdata\\D\\test_d.csv']):
               try:
                    list2=[]
                    line2= line.strip().rstrip(',')
                    line3=line2.split(',')
                    length=len(line3)
                    if length==1:
                        continue
                    for i in range(0,length-1):
                        self.semaphore.acquire()
                        self.no_of_request+=1
                        self.patial_session=line3[0:i+1]
                        self.recomendation_list=om.recommend(line3[i],self.dic1)
                        self.recomendation_list_aw=self.aw.recommend(self.patial_session)
                        self.recomendation_list_hw=self.hw.recommend(self.patial_session)
                        print self.recomendation_list_aw
                        
                        len1=len(self.recomendation_list)
                        if len1==0:
                            self.no_request+=1
                        if not len1==0:
                            self.count+=1
                            j=i+1
                            self.actual=line3[j]
                            results=om.evaluate(self.recomendation_list,self.actual,self.count,self.accuracy) 
                            self.results_aw=self.aw.evaluate(self.recomendation_list_aw,self.actual)
                            self.results_hw=self.hw.evaluate(self.recomendation_list_hw,self.actual)
                            self.accuracy=results[0] 
                            self.count=results[1]
                            self.correct=results[2]
                            self.coverage=float(self.no_of_request-self.no_request)/float(self.no_of_request)*100
        
                    print "accuracy:", self.accuracy
                    print "coverage", self.coverage
                    print "count", self.count
                    print "correct", self.correct
                    
                    self.dic1=om.train(line,self.dic1)
                    self.aw.continous_train(line)
                    self.hw.continous_train(line)
               except:
                    continue
                 
    def getAccuracy(self):
        return str(self.accuracy*100)
    def getCoverage(self):
        return str(self.coverage)
    def getPartialSession(self):
        rec_partial = ','.join(str(i) for i in self.patial_session)
        return str(rec_partial)
    def getRecommendationList(self):
        rec_string = ','.join(str(i) for i in self.recomendation_list)
        return str(rec_string)
    def getCorrect(self):
        return str(self.correct)
    def getActual(self):
        return str(self.actual)
    def getAccuracy_aw(self):
        return str(self.aw.getAccuracy())
    def getCoverage_aw(self):
        return str(self.aw.getCoverage())
    def getRecommendationList_aw(self):
        rec_string = ','.join(str(i) for i in self.recomendation_list_aw)
        return str(rec_string)
    def getCorrect_aw(self):
        return str(self.aw.getCorrect())
    def getAccuracy_hw(self):
        return str(self.hw.getAccuracy())
    def getCoverage_hw(self):
        return str(self.hw.getCoverage())
    def getRecommendationList_hw(self):
        rec_string = ','.join(str(i) for i in self.recomendation_list_hw)
        return str(rec_string)
    def getCorrect_hw(self):
        return str(self.hw.getCorrect())

PATH = os.path.abspath(os.path.dirname("D:\\Server\\"))
class Root(object): pass

#thread1 = myThread()
#thread1.start()
cherrypy.tree.mount(Root(), '/', config={
        '/': {
                'tools.staticdir.on': True,
                'tools.staticdir.dir': PATH,
                'tools.staticdir.index': 'index.html',
            },
    })

cherrypy.tree.mount(HelloWorld(),'/ajax')
cherrypy.engine.start()
cherrypy.engine.block()